# Zhang Jiening perl learning
# April 20th 2007 Yahoo China BeiJing
# basic syntax

#---------function
sub fileStringShow
{
	$filePath = shift;

	if(open (TESTFILE, $filePath))
	{
		local $cout = 0;
		local $lineStr;

		while($lineStr = <TESTFILE>)
		{
			print ("$lineStr\n");
			$cout++;
			if($cout>1000)
			{
				break;
			}
		}
		print "line read cout: $cout\n";

		close(TESTFILE);
	}
}

#-------recusive function call
#rosetta is a mathimatic problem 
#that can be solved with recusive function call programming.
#
#The describtion of this program is:
#there are three colums and n patches,
#at beginning,all the patches stay in the one colum 
#and small ones keep stay upon big ones
#now we want to move these n patches to another colum
#the third colum can be use as temporary
#while moving the rule must be observed 
#that in each colum keep small patches upon big ones
#    
#
#     |			|			|
#     |			|			|
#     |			|			|
#     |			|		  --|--
#     |			|		 ---|---
#     |			|		----|----
# ---------------------------------
#	C			B			A
#
#
sub anotherColum
{
	my($from, $to) = @_;
	my($res)= (ord($from) - ord('A')  + ord($to) - ord('A'));

	print "in anotherColum";

	print "in anotherColum $res";

	if(1== $res)
	{
		return 'C';
	}
	elsif(2 == $res)
	{
		return 'B';
	}
	else
	{
		return 'C';
	}
}

sub moveRosetta
{
	my($num, $from, $to) = @_;

	print("$num === $from === $to");

	my($tmpAnc);

	if($from eq $to)
	{
		return;
	}
	if($num<=0)
	{
		return ; 
	}
	
	if($num==1)
	{
		print ("$from --- $to");
	}
	elsif ($num == 2)
	{
		$tmpAnc = do anotherColum($from,$to);          
		print ("$from --- $tmpAnc");
		print ("$from --- $to");
		print ("$tmpAnc --- $to");
	}
	else
	{
		$tmpAnc = do anotherColum($from,$to);          
		do moveRosetta($num-1,$from, $tmpAnc);
		print ("$from --- $to");
		do moveRosetta($num-1,$tmpAnc, $to);
	}		
}

%days = ("Sunday"    =>0,
		 "Monday"    =>1,
	 	 "Tueseday"  =>2,
		 "Wednseday" =>3,
		 "Turseday"  =>4,
		 "Friday"    =>5,
		 "Santurday" =>6);

%revDays = (0=>"Sunday",
			1=>"Monday",
			2=>"Tueseday",
			3=>"Wednseday",
			4=>"Turseday",
			5=>"Friday",
			6=>"Santurday");

%daysEveryMonth=(1 => 31,
				2 => 28,
				3 => 31,
				4 => 30,
				5 => 31,
				6 => 30,
				7 => 31,
				8 => 31,
				9 => 30,
				10 => 31,
				11 => 30,
				12 => 31);

sub isLeapYear
{
	$yearNum = shift;
	return (  $yearNum%400==0 ? 1 : ($yearNum%100==0 ? 0 : ($yearNum%4==0 ? 1 : 0)) );
}

sub computeDayFromDate
{
	my($inputYear, $inputMon, $inputDay) = @_;
	my(%tmpDEM);
	%tmpDEM = %daysEveryMonth;
	my($tmpy);
	my($tmpm);
	my($dayCount) = 1;

	if(isLeapYear($inputYear))
	{
		print("this is a leap year\n");
		$tmpDEM{2} = 29;
	}

	#some times perl seems fool, I use STDIN to input the month number,
	#perl use it as string, so when I use it as a key to fetch how many days the month have
	#I can not get what I expected.I do not know whether there is method to convert variale from string to number
	#so I just use such ugly way to do the convert 
	++$inputMon;
	--$inputMon;

	if($inputDay>$tmpDEM{$inputMon})
	{
		die("$inputYear - $inputMon - $inputDay is not a legal date");
	}

#------2001-01-01 is monday
	if($inputYear>=2001)
	{
		for($tmpy = 2001; $tmpy<$inputYear; ++$tmpy)
		{
			if(isLeapYear($tmpy))
			{
				$dayCount+=2;
			}
			else
			{
				$dayCount+=1;
			}
			print("\t$dayCount");
		}	
	}
	else
	{
		for($tmpy = 2000; $tmpy>=$iYear; --$tmpy)
		{
			if(isLeapYear($tmpy))
			{
				$dayCount -=2;
			}
			else
			{
				$dayCount -=1;
			}
			print("\t$dayCount");
		}
	}
	print "\n";

	for($tmpm=1; $tmpm<$iMon; ++$tmpm)
	{
		$dayCount += $daysEveryMonth{$tmpm};

		print("\t$dayCount");
	}

	print "\n";
	$dayCount += ($iDay - 1);

	print("\t$dayCount");
	print "\n";
	$dayCount %= 7;

	print("\t$dayCount\n");
	return $dayCount;
}

#-----------------------------------------------------------------------------------
#---------string print
#-----------------------------------------------------------------------------------

print (" hello world!, perl program by zjn \n");

#---------integer
$a=0;
$b=10;
$b+=$a;
print ("$b+$a\n");
print ('$b+$a\n');
print ($b."");
$tmpA = 'A';
$tmpB = 'B';
$tmpC = $tmpB - $tmpA;
print "tmpC = $tmpC";
#die "";

#---------array
@cols = (1,2,3,4,5,6,7,8,9);

@rows = (1,2,3,4,5,6,7,8,9);
print (@cols."");
print ("@cols\n");

for($i = 0; $i<@rows; ++$i)
{
	print "";
	for($j = 0; $j<=$i; ++$j)
	{
		print ("@rows[$i]*@cols[$j]=".@rows[$i]*@cols[$j]."\t");	
	}
}

#--------file read
open (TESTFILE, "./pltest.txt") || die ("Could not open file"); 

$cout = 0;
$lineStr;
while($lineStr = <TESTFILE>)
{
	print ("$lineStr\n");
	$cout++;
	if($cout>1000)
	{
		break;
	}
}

print "line read cout: $cout\n";

close(TESTFILE);

#--------file read
# >> 表示在文件末尾添加
# >  表示抹去原文件，然后写入新内容
#open (TESTFILE, ">>./pltest.txt") || die ("Could not open file"); 
#for($i = 0; $i<@rows; ++$i)
#{
#	print TESTFILE "";
#	for($j = 0; $j<=$i; ++$j)
#	{
#		print TESTFILE ("@rows[$i]*@cols[$j]=".@rows[$i]*@cols[$j]."\t");	
#	}
#}

#close(TESTFILE);

#-------sub function call
$tmpFileName = "./pltest.txt";
do fileStringShow ($tmpFileName);

#-------rosetta function call
#do moveRosetta(5,"A","C");

while(($tmpKey, $tmpVal) = each(%days))
{
	print("$tmpKey => $tmpVal\t");
}
print("\n");

foreach $tmpKey (sort keys(%daysEveryMonth))
{
	print("$tmpKey => $daysEveryMonth{$tmpKey}\t");
}
print("\n");

#------compute day of week from a date
print("input the year num:\t");
$iYear = <STDIN>;
if($iYear<1400 || $iYear>2500)
{
	die("input a year not far away from 2000");
}

print("input the month num:\t");
$iMon = <STDIN>;
if($iMon<1 || $iMon>12)
{
	die("mon number less than 12 and larger than 1");
}

print("input the day num:\t");
$iDay = <STDIN>;
if($iDay<1 || $iDay>31)
{
	die("day number less than 31 and larger than 1");
}

$inputStr = " compute day of date : $iYear "." $iMon "." $iDay"; 
print("$inputStr\n");

$theComputedDay = computeDayFromDate($iYear, $iMon, $iDay);

print("that day is  $revDays{$theComputedDay}\n");
